package com.xinting.piano.lib.audio;

import android.media.MediaPlayer;
import android.media.MediaRecorder;

import java.io.IOException;

/**
 * Created by wuxinting on 15/10/30.
 * 音频处理，录音、播放控制
 */
public class PAudio {

    public enum Status {
        PLAY, //正在播放
        PAUSE, //暂停
        STOP, //停止
        RECORD, //正在录制
    }

    private static PAudio audio;

    private MediaRecorder mRecorder;
    private MediaPlayer mPlayer;
    private IOnStatusChangeListener listener;

    //播放的位置
    private int currentPosition = 0;
    private Status status = Status.STOP;

    //需要被播放，或者录入音频的文件路径
    private String path;
    private boolean bForPlay;
    private OnPlayCompleteListener playCompleteListener;

    private PAudio() {
        mPlayer = new MediaPlayer();
        playCompleteListener = new OnPlayCompleteListener();
    }

    public static PAudio getInstance() {
        if (audio == null) {
            synchronized (PAudio.class) {
                if (audio == null) {
                    audio = new PAudio();
                }
            }
        }
        return audio;
    }

    public IOnStatusChangeListener getStatusChangeListener() {
        return listener;
    }

    public void setOnStatusChangeListener(IOnStatusChangeListener listener) {
        this.listener = listener;
    }

    public String getPath() {
        return path;
    }

    /**
     * 设置文件路径
     * @param path 文件路径
     * @param bForPlay 是否是播放，否则为录音
     */
    public void setPath(String path, boolean bForPlay) throws IOException {
        this.path = path;
        this.bForPlay = bForPlay;

        if (bForPlay) {
            try {
                mPlayer.setDataSource(path);
            } catch (IllegalStateException e) {
                mPlayer = null;
                mPlayer = new MediaPlayer();
                mPlayer.setDataSource(path);
            }
            mPlayer.prepare();
            mPlayer.setOnCompletionListener(playCompleteListener);
        }
    }

    /**
     * 录音，并将内容存入file中
     * @param file
     * @throws IOException
     */
    public void record(String file) throws IOException {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOutputFile(file);
        mRecorder.prepare();
        mRecorder.start();

        setStatus(Status.RECORD);
    }

    /**
     * stop record
     */
    public void stopRecord() {
        mRecorder.stop();
        mRecorder.release();

        setStatus(Status.STOP);
    }

    /**
     * 获取播放文件的时长
     * 如果是录音，则返回-1
     */
    public int getDuration() {
        if (bForPlay) {
            return mPlayer.getDuration();
        }
        return -1;
    }

    /**
     * 获取当前播放的进度
     * 如果是录音返回-1
     * @return
     */
    public int getCurrentPosition() {
        if (bForPlay) {
            return mPlayer.getCurrentPosition();
        }
        return -1;
    }

    /**
     * play file
     * @link #setPath
     */
    public void play(){
        mPlayer.start();

        setStatus(Status.PLAY);
    }

    public void pausePlay() {
        if (mPlayer.isPlaying()) {
            mPlayer.pause();
            currentPosition = mPlayer.getCurrentPosition();

            setStatus(Status.PAUSE);
        }
    }

    public void resumePlay() {
        mPlayer.seekTo(currentPosition);
        mPlayer.start();

        setStatus(Status.PLAY);
    }

    public void stopPlay() {
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
            mPlayer.release();

            setStatus(Status.STOP);
        }
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        Status old = this.status;
        this.status = status;

        if (listener != null) {
            listener.onStatusChange(old, this.status);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        if (mRecorder != null) {
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
        }

        if (mPlayer != null) {
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
        }
        super.finalize();
    }

    /**
     * 播放完成的监听
     */
    private class OnPlayCompleteListener implements MediaPlayer.OnCompletionListener {

        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            setStatus(Status.STOP);
        }
    }

    /**
     * 状态变化监听器
     */
    public interface IOnStatusChangeListener {

        /**
         * 当状态变化时调用
         * @param before 之前的状态
         * @param cur 当前的状态
         */
        void onStatusChange(Status before, Status cur);

    }
}
